// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.iso;

import gnu.trove.set.hash.THashSet;
import java.util.ArrayList;
import zombie.iso.areas.IsoBuilding;

public class IsoGridOcclusionData {
    public static final int MAXBUILDINGOCCLUDERS = 3;
    private static final THashSet<IsoBuilding> _leftBuildings = new THashSet<>(3);
    private static final THashSet<IsoBuilding> _rightBuildings = new THashSet<>(3);
    private static final THashSet<IsoBuilding> _allBuildings = new THashSet<>(3);
    private static int _ObjectEpoch = 0;
    private final ArrayList<IsoBuilding> _leftBuildingsArray = new ArrayList(3);
    private final ArrayList<IsoBuilding> _rightBuildingsArray = new ArrayList(3);
    private final ArrayList<IsoBuilding> _allBuildingsArray = new ArrayList(3);
    private IsoGridSquare _ownerSquare = null;
    private boolean _bSoftInitialized = false;
    private boolean _bLeftOccludedByOrphanStructures = false;
    private boolean _bRightOccludedByOrphanStructures = false;
    private int _objectEpoch = -1;

    public IsoGridOcclusionData(IsoGridSquare inOwnerSquare) {
        this._ownerSquare = inOwnerSquare;
    }

    public static void SquareChanged() {
        _ObjectEpoch++;
        if (_ObjectEpoch < 0) {
            _ObjectEpoch = 0;
        }
    }

    public void Reset() {
        this._bSoftInitialized = false;
        this._bLeftOccludedByOrphanStructures = false;
        this._bRightOccludedByOrphanStructures = false;
        this._allBuildingsArray.clear();
        this._leftBuildingsArray.clear();
        this._rightBuildingsArray.clear();
        this._objectEpoch = -1;
    }

    public boolean getCouldBeOccludedByOrphanStructures(IsoGridOcclusionData.OcclusionFilter filter) {
        if (this._objectEpoch != _ObjectEpoch) {
            if (this._bSoftInitialized) {
                this.Reset();
            }

            this._objectEpoch = _ObjectEpoch;
        }

        if (!this._bSoftInitialized) {
            this.LazyInitializeSoftOccluders();
        }

        if (filter == IsoGridOcclusionData.OcclusionFilter.Left) {
            return this._bLeftOccludedByOrphanStructures;
        } else {
            return filter == IsoGridOcclusionData.OcclusionFilter.Right
                ? this._bRightOccludedByOrphanStructures
                : this._bLeftOccludedByOrphanStructures || this._bRightOccludedByOrphanStructures;
        }
    }

    public ArrayList<IsoBuilding> getBuildingsCouldBeOccluders(IsoGridOcclusionData.OcclusionFilter filter) {
        if (this._objectEpoch != _ObjectEpoch) {
            if (this._bSoftInitialized) {
                this.Reset();
            }

            this._objectEpoch = _ObjectEpoch;
        }

        if (!this._bSoftInitialized) {
            this.LazyInitializeSoftOccluders();
        }

        if (filter == IsoGridOcclusionData.OcclusionFilter.Left) {
            return this._leftBuildingsArray;
        } else {
            return filter == IsoGridOcclusionData.OcclusionFilter.Right ? this._rightBuildingsArray : this._allBuildingsArray;
        }
    }

    private void LazyInitializeSoftOccluders() {
        boolean _boolean = false;
        int int0 = this._ownerSquare.getX();
        int int1 = this._ownerSquare.getY();
        int int2 = this._ownerSquare.getZ();
        _allBuildings.clear();
        _leftBuildings.clear();
        _rightBuildings.clear();
        _boolean |= this.GetBuildingFloorsProjectedOnSquare(_allBuildings, int0, int1, int2);
        _boolean |= this.GetBuildingFloorsProjectedOnSquare(_allBuildings, int0 + 1, int1 + 1, int2);
        _boolean |= this.GetBuildingFloorsProjectedOnSquare(_allBuildings, int0 + 2, int1 + 2, int2);
        _boolean |= this.GetBuildingFloorsProjectedOnSquare(_allBuildings, int0 + 3, int1 + 3, int2);
        this._bLeftOccludedByOrphanStructures = this._bLeftOccludedByOrphanStructures
            | this.GetBuildingFloorsProjectedOnSquare(_leftBuildings, int0, int1 + 1, int2);
        this._bLeftOccludedByOrphanStructures = this._bLeftOccludedByOrphanStructures
            | this.GetBuildingFloorsProjectedOnSquare(_leftBuildings, int0 + 1, int1 + 2, int2);
        this._bLeftOccludedByOrphanStructures = this._bLeftOccludedByOrphanStructures
            | this.GetBuildingFloorsProjectedOnSquare(_leftBuildings, int0 + 2, int1 + 3, int2);
        this._bRightOccludedByOrphanStructures = this._bRightOccludedByOrphanStructures
            | this.GetBuildingFloorsProjectedOnSquare(_rightBuildings, int0 + 1, int1, int2);
        this._bRightOccludedByOrphanStructures = this._bRightOccludedByOrphanStructures
            | this.GetBuildingFloorsProjectedOnSquare(_rightBuildings, int0 + 2, int1 + 1, int2);
        this._bRightOccludedByOrphanStructures = this._bRightOccludedByOrphanStructures
            | this.GetBuildingFloorsProjectedOnSquare(_rightBuildings, int0 + 3, int1 + 2, int2);
        this._bLeftOccludedByOrphanStructures |= _boolean;
        _leftBuildings.addAll(_allBuildings);
        this._bRightOccludedByOrphanStructures |= _boolean;
        _rightBuildings.addAll(_allBuildings);
        _allBuildings.clear();
        _allBuildings.addAll(_leftBuildings);
        _allBuildings.addAll(_rightBuildings);
        this._leftBuildingsArray.addAll(_leftBuildings);
        this._rightBuildingsArray.addAll(_rightBuildings);
        this._allBuildingsArray.addAll(_allBuildings);
        this._bSoftInitialized = true;
    }

    private boolean GetBuildingFloorsProjectedOnSquare(THashSet<IsoBuilding> tHashSet, int int1, int int3, int int5) {
        boolean _boolean = false;
        int int0 = int1;
        int int2 = int3;

        for (int int4 = int5; int4 < IsoCell.MaxHeight; int2 += 3) {
            IsoGridSquare isoGridSquare0 = IsoWorld.instance.CurrentCell.getGridSquare(int0, int2, int4);
            if (isoGridSquare0 != null) {
                IsoBuilding isoBuilding = isoGridSquare0.getBuilding();
                if (isoBuilding == null) {
                    isoBuilding = isoGridSquare0.roofHideBuilding;
                }

                if (isoBuilding != null) {
                    tHashSet.add(isoBuilding);
                }

                for (int int6 = int4 - 1; int6 >= 0 && isoBuilding == null; int6--) {
                    IsoGridSquare isoGridSquare1 = IsoWorld.instance.CurrentCell.getGridSquare(int0, int2, int6);
                    if (isoGridSquare1 != null) {
                        isoBuilding = isoGridSquare1.getBuilding();
                        if (isoBuilding == null) {
                            isoBuilding = isoGridSquare1.roofHideBuilding;
                        }

                        if (isoBuilding != null) {
                            tHashSet.add(isoBuilding);
                        }
                    }
                }

                if (isoBuilding == null && !_boolean && isoGridSquare0.getZ() != 0 && isoGridSquare0.getPlayerBuiltFloor() != null) {
                    _boolean = true;
                }
            }

            int4++;
            int0 += 3;
        }

        return _boolean;
    }

    public static enum OccluderType {
        Unknown,
        NotFull,
        Full;
    }

    public static enum OcclusionFilter {
        Left,
        Right,
        All;
    }
}
